package lei.h_java8特性.方法引用.Demo;

/**
 * @className: 方法的引用
 * @author: xl
 * @date: 2025/7/18 21:43
 * @Version: 1.0
 * @description:
 */

public class Main {
    public static void main(String[] args) {

        /**
         * 使用方法引用的前提条件
         * 函数式接口：方法引用要和函数式接口的抽象方法签名保持一致。
         * 方法签名匹配：方法引用的参数类型以及返回值类型，要和函数式接口的抽象方法参数类型与返回值类型相同。
         * 上下文明确：编译器能够依据函数式接口的类型，明确知道引用的是哪个方法。
         * 总结
         * 方法引用能够让代码变得更加简洁，不过它必须在函数式接口的上下文中使用，而且要保证方法签名是兼容的。
         */


        //   1. 静态方法引用
        //当函数式接口里的抽象方法需要的参数和返回值类型，与某个静态方法的参数和返回值类型相匹配时，就能够运用静态方法引用。
        // 抽象方法需要的"参数"和"返回值类型"，与某个 静态 方法的"参数"和"返回值类型相匹配"
        StringUtils utils1 = Main::toUpperCase;
        System.out.println(utils1.process("hello")); // 输出: HELLO


        //2. 实例方法引用
        //若函数式接口的抽象方法参数和返回值类型，和某个实例方法的参数与返回值类型一致，就可以采用实例方法引用。
        // 抽象方法"参数"和"返回值类型"，和某个 实例方法 的"参数"与"返回值类型"一致

        Main main = new Main();//实力方法一定的new对象
        StringUtils utils2 = main::reverse;
        System.out.println(utils2.process("hello")); // 输出: olleh


        //3. 对象方法引用（特定类型的任意对象）
        //当函数式接口的抽象方法与某个类的实例方法签名相符时，能使用这种方法引用。
        //  函数式接口的签名 和  实力方法的签名相同
        StringComparator comparator = String::compareToIgnoreCase;
        System.out.println(comparator.compare("hello", "HELLO")); // 输出: 0


        // 4. 构造方法引用
        //要是函数式接口的抽象方法返回的是一个对象，并且该对象的构造方法参数和函数式接口的抽象方法参数一致，就能够使用构造方法引用。
        //总结： 构造方法的参数  和  抽象方法的参数一致   返回的对象和构造方法的对象相同
        PersonFactory factory = Person2::new;
        Person2 person = factory.create("Alice", 30);
        System.out.println(person); // 输出: Person{name='Alice', age=30}

    }

    public static String toUpperCase(String s) {
        return s.toUpperCase();
    }

    public String reverse(String s) {
        return new StringBuilder(s).reverse().toString();
    }
}




